﻿using System;
using System.Collections;
using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using XLua;

public class Joystick : ScrollRect,IPointerDownHandler,IPointerUpHandler,IDragHandler
{
   private float radius;
   public Vector2 stickPosition;
   private GameObject bgActive;
   private GameObject bgInActive;
   private Action<Vector2,float> onDrag;
   private LuaFunction onDragLua;
   private LuaFunction onTouchStartLua;
   private LuaFunction onTouchEndLua;
   private Action<Vector2> onTouchDown;
   private Action<Vector2> onTouchUp;
   private Action onPress;
   private float pressCd = 0;
   private float lastPressTime;
   private bool isActive;

   private RectTransform bgTrans;
   private RectTransform bgBtnTrans;
   private RectTransform rootTrans;

   private RectTransform viewportTrans;

   private bool isInArea;
   
   private Vector2 viewPortOriginPosition;
   private Vector2 viewPortSize;

   private Camera uiCamera;
   
   public void Init(Camera uiCamera)
   {
      this.uiCamera = uiCamera;
      bgActive = viewport.Find("bgActive").gameObject;
      radius = bgActive.GetComponent<RectTransform>().sizeDelta.x / 2;
      bgInActive = viewport.Find("bgInActive").gameObject;
      bgTrans = bgActive.GetComponent<RectTransform>();
      bgBtnTrans = bgInActive.GetComponent<RectTransform>();
      rootTrans = GetComponent<RectTransform>();
      viewportTrans = viewport.GetComponent<RectTransform>();
      isActive = false;
      isInArea = false;
      viewPortOriginPosition = viewport.anchoredPosition;
      viewPortSize = viewport.sizeDelta;
      UpdateActive();
   }

   public void SetOnDrag(Action<Vector2,float> onDrag)
   {
      this.onDrag = onDrag;
   }

   public void SetOnDrag(LuaFunction function)
   {
      this.onDragLua = function;
   }

   public void SetOnTouchDown(Action<Vector2> onTouchDown)
   {
      this.onTouchDown = onTouchDown;
   }

   public void SetOnTouchUp(Action<Vector2> onTouchUp)
   {
      this.onTouchUp = onTouchUp;
   }
   
   public void SetOnTouchStart(LuaFunction onTouchStart)
   {
      this.onTouchStartLua = onTouchStart;
   }

   public void SetOnPress(Action onPress,float cd)
   {
      this.onPress = onPress;
      this.pressCd = cd;
   }

   private void UpdateActive()
   {
      bgActive.SetActive(isActive);
      bgInActive.SetActive(!isActive);
   }
   
   public void SetOrientation(Vector2 orientation)
   {
      content.localPosition = orientation.normalized * radius;
   }

   public void UpdateJoystick()
   {
      if (!Application.isPlaying || bgTrans == null)
      {
         return;
      }
      if (content.localPosition.magnitude > radius)
      {
         content.localPosition = content.localPosition.normalized * radius;
      }

      if (content.localPosition.sqrMagnitude <= 0.0001f)
      {
         stickPosition = Vector3.zero;
         bgTrans.localEulerAngles = new Vector3(0, 0,0);
      }
      else
      {
         stickPosition = content.localPosition.normalized;
         float angle = Mathf.Atan(-stickPosition.x / stickPosition.y) * Mathf.Rad2Deg;
         bgTrans.localEulerAngles = new Vector3(0, 0,angle);
      }
      
      onDrag?.Invoke(stickPosition,content.localPosition.sqrMagnitude);
      onDragLua?.Action(stickPosition,content.localPosition.sqrMagnitude);
      if (isActive && TimeManager.logicTime - lastPressTime > pressCd)
      {
         lastPressTime = TimeManager.logicTime;
         onPress?.Invoke();
      }
   }

   public void OnPointerDown(PointerEventData eventData)
   {
      onTouchDown?.Invoke(eventData.position);
      
      RectTransformUtility.ScreenPointToLocalPointInRectangle(rootTrans,eventData.position,uiCamera,out var localPoint);
      viewportTrans.localPosition = localPoint;
      //pressPos += new Vector2(Screen.width / 2f, Screen.height / 2f);
      //var offset = eventData.pressPosition - btnScreenPos;
      //content.localPosition = offset;
      //isInArea = offset.magnitude <= radius;
      isActive = true;
      UpdateActive();
   }
   
   public void OnPointerUp(PointerEventData eventData)
   {
      viewport.anchoredPosition = viewPortOriginPosition;
      onTouchUp?.Invoke(eventData.position);
      content.localPosition = Vector3.zero;
      isActive = false;
      UpdateActive();
   }

   public override void OnDrag(PointerEventData eventData)
   {
      var btnScreenPos = RectTransformUtility.WorldToScreenPoint(uiCamera, bgBtnTrans.position);
      //pressPos += new Vector2(Screen.width / 2f, Screen.height / 2f);
      var offset = eventData.position - btnScreenPos;
      isInArea = offset.magnitude <= radius;
      content.localPosition = offset;
   }
}
